<!--
  文件描述：选择图片
  创建时间：2023/10/7 10:02
  创建人：二
-->
<template>
  <div class="select-image-wrap">

    <draggable
      v-model="imageList"
      @update="onUpdate"
    >
      <transition-group
        tag="div"
        name="list-complete"
      >
        <div
          class="image-item"
          v-for="(d, i) in imageList"
          :key="d.id"
          :style="{ width: `${width}px`, height: `${width}px` }"
        >
          <!-- 预览图 -->
          <a :href="mixinFileUrl(d.path)" target="_blank">
            <div class="img-cover" :style="{ backgroundImage: `url('${mixinFileUrl(d.path)}')` }"></div>
          </a>
          <!-- 删除文件 -->
          <div class="icon-close" v-if="!preview" @click="removeImage(i)">
            <i class="el-icon-close"/>
          </div>
        </div>
      </transition-group>
    </draggable>

    <!-- 图片选择器 -->
    <!-- 如果单选, imageList 无内容时 显示 -->
    <!-- 如果多选, imageList 数量小于 maxNum 显示 -->
    <div
      v-show="(!multiple && imageList.length <= 0) || (multiple && imageList.length < maxNum)"
      class="selector"
      :style="{width: `${width}px`, height: `${width}px`}"
      title="点击选择图片"
      @click="handleSelectImage"
    >
      <i class="el-icon-plus icon-plus"></i>
    </div>

    <!-- 图片选择器 -->
    <MSelectImageList
      ref="MSelectImageList"
      :multiple="multiple"
      :maxNum="maxNum"
      :selectedNum="imageList.length"
      @handleSubmit="updateImageList"
    />
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import MSelectImageList from './MSelectImageList'
export default {
  name: 'MSelectImage',
  components: {
    MSelectImageList,
    draggable
  },
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    // 预览
    preview: {
      type: Boolean,
      default: false
    },
    // 多选模式, 如果false为单选
    multiple: {
      type: Boolean,
      default: false
    },
    // 最大选择的数量限制, multiple模式下有效
    maxNum: {
      type: Number,
      default: 100
    },
    // 默认选中的图片
    defaultList: {
      type: Array,
      default: () => []
    },
    // 元素的尺寸(宽)
    width: {
      type: Number,
      default: 80
    },
    // 默认图片id字段
    imageId: {
      type: String,
      default: 'id'
    },
    // 默认图片路径字段
    imagePath: {
      type: String,
      default: 'path'
    }
  },
  data() {
    return {
      // 选择的图片列表
      imageList: []
    }
  },
  computed: {
    srcList() {
      return this.imageList.map(d => d.path)
    }
  },
  watch: {
    // 设置默认数据
    defaultList: {
      // 首次加载的时候执行函数
      immediate: true,
      handler (val) {
        const { imageList, imageId, imagePath } = this
        if (val.length) {
          if (imagePath === 'path' && imageId === 'id') {
            this.imageList = val;
          } else {
            this.imageList = val.map(item => {
              return {
                id: item[imageId],
                path: item[imagePath]
              }
            })
          }
          this.onChange()
        }
      },
      deep: true
    }
  },
  methods: {
    // 打开图片列表
    handleSelectImage () {
      this.$refs.MSelectImageList.open()
    },
    // 拖动排序后的回调事件
    onUpdate() {
      this.onChange()
    },
    // 选择图片确认回调
    updateImageList(result) {

      if (result.length) {
        // 记录选中的图片列表
        const { multiple, imageList } = this
        this.imageList = multiple ? imageList.concat(result) : result;
        this.onChange()
      }

    },
    // 删除图片
    removeImage(index) {
      this.imageList.splice(index, 1)
    },
    // 触发change事件
    onChange() {
      const { multiple, imageList } = this;
      if (imageList.length <= 0) {
        return this.$emit('change', multiple ? [] : '')
      }
      // 返回id
      const imageId = multiple ? imageList.map(item => item.id) : imageList[0].id
      // 触发change事件
      return this.$emit('change', imageId)

    }
  }
}
</script>

<style lang="scss" scoped>
  .select-image-wrap {

    .image-item {
      position: relative;
      float: left;
      padding: 2px;
      border: 1px dashed #ddd;
      background: #fff;
      line-height: 0;
      font-size: 0;
      .img-cover {
        display: block;
        width: 100%;
        height: 100%;
        background: no-repeat center center / 100%;
      }
      &:hover {
        border: 1px dashed #a7c3de;
        .icon-close {
          opacity: 1;
        }
      }
      .icon-close {
        position: absolute;
        top: -8px;
        right: -8px;
        cursor: pointer;
        font-size: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: #c5c5c5;
        color: #fff;
        padding: 1px;
        border-radius: 50%;
        opacity: 0;
        &:hover {
          background: #7d7d7d;
        }
      }
    }
    // 选择器
    .selector {
      width: 80px;
      height: 80px;
      float: left;
      border: 1px dashed #e2e2e2;
      text-align: center;
      color: #dad9d9;
      cursor: pointer;
      display: flex;
      justify-content: center;
      align-items: center;
      &:hover {
        border: 1px dashed #40a9ff;
        color: #40a9ff;
      }
      .icon-plus {
        font-size: 32px;
      }
    }
    .image-item,
    .selector {
      margin-right: 10px;
      margin-bottom: 10px;
    }
  }
  .list-complete-item {
    transition: all 1s;
    display: inline-block;
    margin-right: 10px;
  }
  .list-complete-enter, .list-complete-leave-to
    /* .list-complete-leave-active for below version 2.1.8 */ {
    opacity: 0;
    transform: translateY(30px);
  }
  .list-complete-leave-active {
    position: absolute;
  }
</style>
